from fastapi import Depends, HTTPException,status
from fastapi.security import OAuth2PasswordBearer
from jose import JWTError
from sqlmodel import Session, select

from .security import verify_token
from ..models.permission import User,Role,UserRole,Permission,RolePermission
from ..schemas.permission import TokenData
from .database import get_session

oauth2_scheme = OAuth2PasswordBearer(tokenUrl="api/v1/auth/login")

def get_user_permissions(session: Session, user:User):
    """获取用户的所有权限代码"""
    if user.is_superuser:
        # 超级用户有所有权限
        permissions = session.exec(select(Permission.code)).all()
        return permissions
    # # 获取用户的角色
    # user_roles = session.exec(
    #     select(Role).join(UserRole).where(UserRole.user_id == user.id)
    # ).all()
    # if not user_roles:
    #     return []
    #
    # role_ids = [role.id for role in user_roles]
    #
    # # 获取角色的权限
    # permissions = session.exec(
    #     select(Permission.code)
    #     .join(RolePermission)
    #     .where(RolePermission.role_id.in_(role_ids))
    # ).all()

    permissions = session.exec(
        select(Permission.code)
        .join(RolePermission, Permission.id == RolePermission.permission_id)
        .join(UserRole, RolePermission.role_id == UserRole.role_id)
        .where(UserRole.user_id == user.id)
    ).all()

    return list(set(permissions))   # 把权限代码去重封装为list返回

async def get_current_user(
        token: str = Depends(oauth2_scheme),
        session: Session = Depends(get_session)
):
    """获取当前用户"""
    credentials_exception = HTTPException(
        status_code=status.HTTP_401_UNAUTHORIZED,
        detail="无法验证凭证",
        headers={"WWW-Authenticate": "Bearer"}
    )

    try:
        payload = verify_token(token)
        if payload is None:
            raise credentials_exception
        username: str = payload.get("sub")
        if username is None:
            raise credentials_exception
        token_data = TokenData(username=username)
    except JWTError:
        raise credentials_exception

    user = session.exec(
        select(User).where(User.username == token_data.username)
    ).first()
    if user is None:
        raise credentials_exception
    return user

async def get_current_active_user(current_user: User = Depends(get_current_user)):
    """获取当前活跃用户"""
    if not current_user.is_active:
        raise HTTPException(status_code=400, detail="用户未激活")
    return current_user

def get_current_user_with_permissions(
        token: str = Depends(oauth2_scheme),
        session: Session = Depends(get_session)
):
    """获取当前用户及其权限"""
    credentials_exception = HTTPException(
        status_code=status.HTTP_401_UNAUTHORIZED,
        detail="无法验证凭证",
        headers={"WWW-Authenticate": "Bearer"}
    )
    try:
        payload = verify_token(token)
        if payload is None:
            raise credentials_exception
        username = payload.get("sub")
        if username is None:
            raise credentials_exception
        permissions:list[str] = payload.get("permissions",[])
        token_data = TokenData(username=username,permissions=permissions)
    except JWTError:
        raise credentials_exception

    user = session.exec(
        select(User).where(User.username == token_data.username)
    ).first()
    if user is None:
        raise credentials_exception
    if not user.is_active:
        raise HTTPException(status_code=400, detail="用户未激活")
    # 如果权限未在token中，从数据库获取
    if not token_data.permissions:
        token_data.permissions = get_user_permissions(session, user)
    return {"user": user, "permissions": token_data.permissions}

